package com.study.utils;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Enumeration;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;

public class FileUtil {
	private static final int buffer = 2048;

	/**
	 * 解压Zip文件
	 * 
	 * @param path
	 *            文件目录
	 * 
	 */
	public static void unZip(String path) {
		int count = -1;
		String savepath = "";

		File file = null;
		InputStream is = null;
		FileOutputStream fos = null;
		BufferedOutputStream bos = null;

		savepath = path.substring(0, path.lastIndexOf(".")) + File.separator; // 保存解压文件目录
		new File(savepath).mkdir(); // 创建保存目录
		ZipFile zipFile = null;
		try {
			zipFile = new ZipFile(path); // 解决中文乱码问题
			Enumeration<?> entries = zipFile.entries();

			while (entries.hasMoreElements()) {
				byte buf[] = new byte[buffer];

				ZipEntry entry = (ZipEntry) entries.nextElement();

				String filename = entry.getName();
				boolean ismkdir = false;

				// 检查此文件是否带有文件夹
				if (filename.lastIndexOf("/") != -1) {
					ismkdir = true;
				}
				filename = savepath + filename;

				// 如果是文件夹先创建
				if (entry.isDirectory()) {
					file = new File(filename);
					file.mkdirs();
					continue;
				}
				file = new File(filename);

				// 如果是目录先创建
				if (!file.exists()) {
					if (ismkdir) {
						// 目录先创建
						new File(filename.substring(0, filename.lastIndexOf("/"))).mkdirs();
					}
				}

				// 创建文件
				file.createNewFile();

				is = zipFile.getInputStream(entry);
				fos = new FileOutputStream(file);
				bos = new BufferedOutputStream(fos, buffer);

				while ((count = is.read(buf)) > -1) {
					bos.write(buf, 0, count);
				}
				bos.flush();
				bos.close();
				fos.close();

				is.close();
			}

			zipFile.close();

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if (bos != null) {
					bos.close();
				}
				if (fos != null) {
					fos.close();
				}
				if (is != null) {
					is.close();
				}
				if (zipFile != null) {
					zipFile.close();
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 删除文件
	 * 
	 * @param filePath
	 *            文件目录
	 */
	public void deleteFile(String filePath) {
		File file = new File(filePath);
		if (file.exists() && file.isFile())
			file.delete();
	}

	/**
	 * 复制文件到中间目录，再对文件进行压缩，对源文件进行删除
	 * 
	 * @param name
	 *            待压缩文件目录名
	 * @param oldPath
	 *            压缩文件路径 ，oldPath+name为待压缩文件的完整目录
	 * @param MiddlePath
	 *            中间目录
	 * @param zipFilePath
	 *            压缩文件存放路径
	 */
	public void fileToZip(String name, String oldPath, String MiddlePath, String zipFilePath) {
		Date d = new Date();
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
		String taday = df.format(d).toString();

		try {
			List<String> fileName = new ArrayList<String>();
			// 获取目标文件夹下的所有文件
			fileName = readFile(oldPath);
			if (fileName.size() > 0) {
				copyFile(fileName, oldPath + name, MiddlePath);
			}

			// 压缩存储
			String sourceFilePath = MiddlePath;
			// 压缩文件的存储位置
			boolean status = fileToZip(sourceFilePath + File.separator + taday, zipFilePath, name);
			// 判断是否压缩成功，压缩成功后删除中间目录文件文件
			if (status) {
				// deleteFileAll(MiddlePath);
			}
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
	}

	/**
	 * 递归读取文件夹下所有的文件
	 * 
	 * 
	 * @param filepath
	 *            文件目录
	 * @return 返回文件夹下的所有文件的文件名
	 * @throws FileNotFoundException
	 * @throws IOException
	 */
	public static List<String> readFile(String filepath) throws FileNotFoundException, IOException {
		List<String> fileNameList = new ArrayList<String>();
		try {
			File file = new File(filepath);
			if (!file.isDirectory()) {

			} else if (file.isDirectory()) {
				String[] filelist = file.list();
				for (int i = 0; i < filelist.length; i++) {
					File readfile = new File(filepath + "\\" + filelist[i]);
					if (!readfile.isDirectory()) {
						fileNameList.add(readfile.getName());
					} else if (readfile.isDirectory()) {
						readFile(filepath + "\\" + filelist[i]);
					}
				}
			}

		} catch (FileNotFoundException e) {
			System.out.println("readfile()   Exception:" + e.getMessage());
		}
		return fileNameList;
	}

	// 删除目录下的所有文件
	/**
	 * 递归删除目录下下所有的文件
	 * 
	 * @param filepath  待删除文件目录
	 * @throws FileNotFoundException
	 * @throws IOException
	 */
	public static void deleteFileAll(String filepath) throws FileNotFoundException, IOException {
		try {
			File file = new File(filepath);
			if (file.isDirectory()) {
				String[] filelist = file.list();
				for (int i = 0; i < filelist.length; i++) {
					File readfile = new File(filepath + "\\" + filelist[i]);
					if (!readfile.isDirectory()) {
						readfile.delete();
					} else if (readfile.isDirectory()) {
						readFile(filepath + "\\" + filelist[i]);
					}
				}
			}

		} catch (FileNotFoundException e) {
			System.out.println("readfile()   Exception:" + e.getMessage());
		}catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
	}

	/**
	 * 将原目录下的所有文件复制到新目录下
	 * 
	 * @param fileList  原目录下的所有文件
	 * @param oldPath   原文件目录
	 * @param nowPath 	中间目录（暂存）
	 */
	public static void copyFile(List<String> fileList, String oldPath, String nowPath) {
		Date d = new Date();
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
		String taday = df.format(d).toString();

		for (int i = 0; i < fileList.size(); i++) {
			doCopyFile(oldPath + "\\" + fileList.get(i), nowPath + "\\" + taday + "\\" + fileList.get(i));
		}
	}

	public static void doCopyFile(String oldPath, String newPath) {
		try {
			File oldfile = new File(oldPath);
			if (oldfile.exists()) { // 文件存在时
				InputStream inStream = new FileInputStream(oldPath); // 读入原文件
				// 新文件是否存在,不存在就创建文件
				if (!new File(newPath).exists()) {
					new File(newPath).getParentFile().mkdirs();
				}
				FileOutputStream fs = new FileOutputStream(newPath);
				byte[] buffer = new byte[1444];
				while ((inStream.read(buffer)) != -1) {
					fs.write(buffer);
				}
				inStream.close();
				fs.close();
			}
		} catch (Exception e) {
			System.out.println("复制单个文件操作出错");
			e.printStackTrace();

		}
	}

	// 打包文件目录下的所有文件
	/**
	 * 压缩目标文件夹的所有文件为zip格式
	 * 
	 * @param sourceFilePath 待压缩文件目录
	 * @param zipFilePath  压缩文件存储目录
	 * @param fileName  压缩文件名称
	 * @return
	 */
	public static boolean fileToZip(String sourceFilePath, String zipFilePath, String fileName) {
		boolean flag = false;
		File sourceFile = new File(sourceFilePath);
		FileInputStream fis = null;
		BufferedInputStream bis = null;
		FileOutputStream fos = null;
		ZipOutputStream zos = null;

		if (sourceFile.exists() == false) {
			System.out.println("待压缩的文件目录：" + sourceFilePath + "不存在.");
		} else {
			try {
				File zipFile = new File(zipFilePath + "/" + fileName + ".zip");
				File[] sourceFiles = sourceFile.listFiles();
				// if (null == sourceFiles || sourceFiles.length < 1) {
				// System.out.println("待压缩的文件目录：" + sourceFilePath + "里面不存在文件，无需压缩.");
				// } else {
				fos = new FileOutputStream(zipFile);
				zos = new ZipOutputStream(new BufferedOutputStream(fos));
				byte[] bufs = new byte[1024 * 10];
				if (sourceFiles.length > 0) {
					for (int i = 0; i < sourceFiles.length; i++) {
						// 创建ZIP实体，并添加进压缩包
						ZipEntry zipEntry = new ZipEntry(sourceFiles[i].getName());
						zos.putNextEntry(zipEntry);
						// 读取待压缩的文件并写进压缩包里
						fis = new FileInputStream(sourceFiles[i]);
						bis = new BufferedInputStream(fis, 1024 * 10);
						int read = 0;
						while ((read = bis.read(bufs, 0, 1024 * 10)) != -1) {
							zos.write(bufs, 0, read);
						}

						if (null != bis) {
							bis.close();
							bis = null;
						}
						if (null != fis) {
							fis.close();
							fis = null;
						}
						zos.closeEntry();
					}
				}
				flag = true;

				if (null != zos) {
					zos.close();
					zos = null;
				}
				if (null != fos) {
					fos.close();
					fos = null;
				}
				// }
				zipFile = null;
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				// 关闭流
				try {
					if (null != bis) {
						bis.close();
						bis = null;
					}
					if (null != zos) {
						zos.close();
						zos = null;
					}
					if (null != fis) {
						fis.close();
						fis = null;
					}
					if (null != fos) {
						fos.close();
						fos = null;
					}
					sourceFile = null;
				} catch (IOException e) {
					System.out.println("===finally===IOException===" + e.getMessage().toString());
					throw new RuntimeException(e);
				}
			}
		}
		return flag;
	}

}
